package com.itheima.servcie;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.itheima.bean.CodeBean;
import com.itheima.dbservice.UserInfoServiceApi;
import com.itheima.exception.CommonException;
import com.itheima.mongoservice.CommentsServiceApi;
import com.itheima.mongoservice.MovementServiceApi;
import com.itheima.pojo.UserInfo;
import com.itheima.pojo.mongo.Comment;
import com.itheima.pojo.mongo.Movement;
import com.itheima.vo.mongo.AllVo;
import com.itheima.vo.mongo.CommentsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.swing.text.ZoneView;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class CommentsService {
    @DubboReference
    private UserInfoServiceApi userInfoServiceApi;
    @DubboReference
    private MovementServiceApi movementServiceApi;
    @DubboReference
    private CommentsServiceApi commentsServiceApi;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public AllVo getComments(Integer page, Integer pagesize, String movementId) {
        //获取对应动态的评论
        List<Comment> comments = commentsServiceApi.getMovementComments(page, pagesize, movementId);

        //填充集合
        List<CommentsVo> list = new ArrayList<>();
        for (Comment comment : comments) {
            //获取对应评论的用户信息
            UserInfo commenterInfo = userInfoServiceApi.getUserInfoById(comment.getPublishUserId());
            CommentsVo commentsVo = new CommentsVo();
            //评论(2为是否评论)
            if (comment.getCommentType() == 2) {
                //封装CommentsVo
                commentsVo.setId(comment.getId().toHexString());
                commentsVo.setAvatar(commenterInfo.getAvatar());
                commentsVo.setNickname(commenterInfo.getNickname());
                commentsVo.setContent(comment.getContent());
                commentsVo.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(comment.getCreated())));
                commentsVo.setLikeCount(comment.getLikeCount() != null ? comment.getLikeCount() : 0);
            }
            //是否点赞(1为点赞)
            if (comment.getCommentType() == 1){
                commentsVo.setHasLiked(1);
            }
            list.add(commentsVo);
        }
        AllVo allVo = new AllVo();
        allVo.setPage(page);
        allVo.setPagesize(pagesize);
        allVo.setPages(comments.size()/pagesize+1);
        allVo.setCounts(comments.size());
        allVo.setItems(list.toArray());
        return allVo;
    }

    public void comment(Comment comment) {
        //获取当前用户id
        Long uid = Convert.toLong(stringRedisTemplate.opsForValue().get(CodeBean.ID));
        //检查用户被冻结范围
        log.info(CodeBean.FREEZE_USER + uid);
        String map1 = Convert.toStr(stringRedisTemplate.opsForValue().get(CodeBean.FREEZE_USER + uid));
        Map freezeMap = JSONUtil.toBean(map1, Map.class);
        //检查是否有该用户
        if (freezeMap.size() != 0){
            //检查用户被冻结范围，1为冻结登录，2为冻结发言，3为冻结发布动态
            Integer freezingRange = Convert.toInt(freezeMap.get("freezingRange"));
            if (ObjectUtil.equal(2, freezingRange)){
                throw new CommonException("您已被禁言");
            }
        }
        //2为评论
        saveComment(comment.getPublishId(), 2, comment.getContent());
    }

    public Integer like(ObjectId id) {
        //判断是否已点赞
        String uid = stringRedisTemplate.opsForValue().get(CodeBean.ID);
        boolean res = commentsServiceApi.isExist(id, uid, 1);
        if (res){
            throw new CommonException("已点赞，不能再点了哦");
        }
        //检查是否点赞
        if (stringRedisTemplate.opsForHash().hasKey(CodeBean.MOVEMENTS_INTERACT_KEY + Convert.toStr(id), CodeBean.MOVEMENT_LIKE_HASHKEY + uid)){
            throw new CommonException("已点赞，不能再点了哦");
        }
        //1为点赞
        saveComment(id, 1, null);
        //redis存储已点赞动态信息
        stringRedisTemplate.opsForHash().put(CodeBean.MOVEMENTS_INTERACT_KEY + Convert.toStr(id),
                                            CodeBean.MOVEMENT_LIKE_HASHKEY + uid, "1");
          //查询喜欢数并返回
//        Movement movementInfo = movementServiceApi.getMovementInfo(Convert.toStr(id));
          //更新表中数据
//        movementInfo.setLikeCount(movementInfo.getLikeCount() + 1);
//        movementServiceApi.updateMovement(movementInfo);
        //获取更新后的信息
        Movement movement = movementServiceApi.getMovementInfo(Convert.toStr(id));
        return movement.getLikeCount();
    }

    //封装Comment
    private void saveComment(ObjectId id, Integer type, String content){
        Comment comment = new Comment();
        comment.setPublishId(id);
        //获取当前动态发布人id
        Movement movement = movementServiceApi.getMovementInfoById(id);
        comment.setUserId(movement.getUserId());
        //获取评论者id
        String uid = stringRedisTemplate.opsForValue().get(CodeBean.ID);
        //封装
        comment.setCommentType(type);
        //封装评论(1点赞  2评论)
        comment.setContent(type == 2 ? content : null);
        comment.setCreated(System.currentTimeMillis());
        comment.setLikeCount(0);
        comment.setPublishUserId(Convert.toLong(uid));
        commentsServiceApi.comment(comment);
        //更新喜欢和评论参数
        addMovementComment(type, movement);
    }

    //更新movement里的喜欢和评论参数(点赞,新增)
    private void addMovementComment(Integer type, Movement movement) {
        Movement movementInfo = new Movement();
        movementInfo.setId(movement.getId());
        if (ObjectUtil.equal(type, 1)) {
            movementInfo.setLikeCount(movement.getLikeCount() != null ? movement.getLikeCount() + 1 : 1);
        }else {
            //保存原始数据，直接存null更新会覆盖原有数据
            if (movement.getLikeCount() != null)
            movementInfo.setLikeCount(movement.getLikeCount());
        }
        if (ObjectUtil.equal(type, 3)) {
            movementInfo.setLoveCount(movement.getLoveCount() != null ? movementInfo.getLoveCount() + 1 : 1);
        }else {
            //保存原始数据，直接存null更新会覆盖原有数据
            if (movement.getLoveCount() != null)
            movementInfo.setLoveCount(movement.getLoveCount());
        }
        if (ObjectUtil.equal(type, 2)) {
            movementInfo.setCommentCount(movement.getCommentCount() != null ? movement.getCommentCount() + 1 : 1);
        }else {
            //保存原始数据，直接存null更新会覆盖原有数据
            if (movement.getCommentCount() != null)
            movementInfo.setCommentCount(movement.getCommentCount());
        }
        //更新到movement
        movementServiceApi.updateMovement(movementInfo);
    }

    //更新movement里的喜欢和评论参数(取消,减少)
    private void deleteMovementComment(Integer type, Movement movement) {
        Movement movementInfo = new Movement();
        movementInfo.setId(movement.getId());
        if (ObjectUtil.equal(type, 1)) {
            movementInfo.setLikeCount(movement.getLikeCount() != 1 ? movement.getLikeCount() - 1 : 0);
        }else {
            //保存原始数据，直接存null更新会覆盖原有数据
            if (movement.getLikeCount() != null)
                movementInfo.setLikeCount(movement.getLikeCount());
        }
        if (ObjectUtil.equal(type, 3)) {
            movementInfo.setLoveCount(movement.getLoveCount() != 1 ? movementInfo.getLoveCount() - 1 : 0);
        }else {
            //保存原始数据，直接存null更新会覆盖原有数据
            if (movement.getLoveCount() != null)
                movementInfo.setLoveCount(movement.getLoveCount());
        }
        if (ObjectUtil.equal(type, 2)) {
            movementInfo.setCommentCount(movement.getCommentCount() != 1 ? movement.getCommentCount() - 1 : 0);
        }else {
            //保存原始数据，直接存null更新会覆盖原有数据
            if (movement.getCommentCount() != null)
                movementInfo.setCommentCount(movement.getCommentCount());
        }
        //更新到movement
        movementServiceApi.updateMovement(movementInfo);
    }

    public Integer dislike(ObjectId id) {
        //取出动态
        Movement movementInfo = movementServiceApi.getMovementInfo(Convert.toStr(id));
        //判断动态是否已点赞
        String uid = stringRedisTemplate.opsForValue().get(CodeBean.ID);
        boolean res = commentsServiceApi.isExist(id, uid, 1);
        if (!res){
            throw new CommonException("未点赞，无法取消");
        }
        //删除数据库点赞数据
        commentsServiceApi.deleteComment(id, uid, 1);
        //redis删除已点赞动态信息
        stringRedisTemplate.opsForHash().delete(CodeBean.MOVEMENTS_INTERACT_KEY + Convert.toStr(id),
                CodeBean.MOVEMENT_LIKE_HASHKEY + uid);
        deleteMovementComment(1, movementInfo);
        //更改动态信息
//        movementInfo.setLikeCount(movementInfo.getLikeCount() - 1);
//        movementServiceApi.updateMovement(movementInfo);
        //查询更新后的信息
        Movement movement = movementServiceApi.getMovementInfo(Convert.toStr(id));
        return movement.getLikeCount();
    }

    public Integer commentLike(ObjectId id) {
        //判断是否已点赞
        String uid = stringRedisTemplate.opsForValue().get(CodeBean.ID);
//        boolean res = commentsServiceApi.isExist(id, uid, 1);
//        if (res){
//            throw new CommonException("已点赞，不能再点了哦");
//        }
        //更新被点赞评论的点赞数
        commentsServiceApi.updateLikeCount(id, true);
        //1为点赞
        Comment comment = new Comment();
        comment.setPublishId(id);
        //获取当前评论发布人id
        Comment commentInfo = commentsServiceApi.getById(id);
        comment.setUserId(commentInfo.getPublishUserId());
        //封装
        comment.setCommentType(1);
        //封装评论(1点赞  2评论)
        comment.setCreated(System.currentTimeMillis());
        comment.setLikeCount(0);
        comment.setPublishUserId(Convert.toLong(uid));
        commentsServiceApi.comment(comment);

//        return commentInfo.getLikeCount() + 1;
        return commentInfo.getLikeCount();
    }

    public Integer commentDislike(ObjectId id) {
        //取出评论
        Comment comment = commentsServiceApi.getById(id);
        //判断是否已点赞
        String uid = stringRedisTemplate.opsForValue().get(CodeBean.ID);
//        boolean res = commentsServiceApi.isExist(id, uid, 1);
//        if (!res){
//            throw new CommonException("未点赞，无法取消");
//        }
        //删除数据库点赞数据
        commentsServiceApi.deleteComment(id, uid, 1);
        //点赞数-1
        commentsServiceApi.updateLikeCount(id, false);

        return comment.getLikeCount();
    }
}
